package com.ljb.android.comm.router.core

import android.app.Activity
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.template.IProvider
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.JsonObject
import com.ljb.android.comm.BuildConfig
import com.ljb.android.comm.common.CommConstant
import com.ljb.android.comm.fragment.CommNotFoundFragment
import com.ljb.android.comm.router.CommRouter
import com.ljb.android.comm.rx.subscribeEx
import com.ljb.android.comm.utils.XLog
import com.ljb.android.component.home.router.IHomeRouterService
import com.ljb.android.component.knowledge.router.IKnowRouterService
import com.ljb.android.component.nav.router.INavRouterService
import com.ljb.android.component.project.router.IProjectRouterService
import com.ljb.android.component.router.IAppRouterService
import com.ljb.android.component.search.router.ISearchRouterService
import com.ljb.android.component.user.router.IUserRouterService
import com.ljb.android.component.user.router.UserRouter
import com.ljb.android.component.wxcode.router.IWXCodeRouterService
import io.reactivex.rxjava3.core.Observable
import net.ljb.kt.utils.RxUtils
import java.util.concurrent.TimeUnit

object RouterManager {

    private val mSchemeHelper by lazy { SchemeHelper() }
    private val mIntercepts by lazy { InterceptGroup() }

    /**
     * 获得Fragment
     * */
    fun getFragment(path: String): Fragment {
        val navigation = ARouter.getInstance().build(path)
            .navigation()
        var fragment: Fragment = CommNotFoundFragment()
        if (navigation != null && navigation is Fragment) {
            fragment = navigation
        }
        return fragment
    }

    /**
     * 跳转 WebView
     * */
    fun goWeb(url: String, title: String = "") {
        goActivity(
            CommRouter.Activity.COMM_WEB,
            Bundle().apply {
                putString("url", url)
                putString("title", title)
            })
    }


    /**
     * 跳转 Activity
     * */
    fun goActivity(path: String, bundle: Bundle? = null) {
        goActivity(null, path, bundle)
    }

    /**
     * 跳转 Activity
     * */
    fun goActivity(context: Context?, path: String, bundle: Bundle? = null) {
        ARouter.getInstance().build(path)
            .with(bundle)
            .navigation(context)
    }

    /**
     * 跳转 ActivityForResult
     * */
    fun goActivityForResult(
        act: Activity,
        path: String,
        bundle: Bundle? = null,
        requestCode: Int
    ) {
        ARouter.getInstance().build(path)
            .with(bundle)
            .navigation(act, requestCode)
    }

    /**
     * 通过Path获取服务
     * */
    fun <T : IProvider> getService(path: String): T? {
        val service = ARouter.getInstance().build(path).navigation()
        return if (service == null) {
            if (BuildConfig.DEBUG) {
                val msg = "not found service by path : [${path}]"
                ToastUtils.showLong(msg)
                XLog.e(Throwable(msg))
            }
            null
        } else {
            service as T
        }
    }


    /**
     * 通过Service的字节码获取服务
     * */
    fun <T> getService(clazz: Class<out T>): T? {
        val service = ARouter.getInstance().navigation(clazz)
        if (service == null && BuildConfig.DEBUG) {
            val msg = "not found service by class : [${clazz.simpleName}]"
            ToastUtils.showLong(msg)
            XLog.e(Throwable(msg))
        }
        return service
    }


    /**
     * 获取App模块服务
     */
    fun getAppService(): IAppRouterService? {
        return getService(IAppRouterService::class.java)
    }

    /**
     * 获取User模块服务
     */
    fun getUserService(): IUserRouterService? {
        return getService(IUserRouterService::class.java)
    }

    /**
     * 获取Home模块服务
     */
    fun getHomeService(): IHomeRouterService? {
        return getService(IHomeRouterService::class.java)
    }

    /**
     * 获取Know模块服务
     * */
    fun getKnowService(): IKnowRouterService? {
        return getService(IKnowRouterService::class.java)
    }

    /**
     * 获取WeChatCode模块服务
     * */
    fun getWXCodeService(): IWXCodeRouterService? {
        return getService(IWXCodeRouterService::class.java)
    }

    /**
     * 获取Nav模块服务
     * */
    fun getNavService(): INavRouterService? {
        return getService(INavRouterService::class.java)
    }

    /**
     * 获取Project模块服务
     * */
    fun getProjectService(): IProjectRouterService? {
        return getService(IProjectRouterService::class.java)
    }

    /**
     * 获取Search模块服务
     * */
    fun getSearchService(): ISearchRouterService? {
        return getService(ISearchRouterService::class.java)
    }


    /**
     * Scheme 路由跳转
     * */
    fun jumpUrl(
        context: Context,
        jumpUrl: String?,
        callBefore: ((context: Context, action: RouterAction) -> Unit)? = null,
        callAfter: ((context: Context, json: String?) -> Unit)? = null
    ) {
        jumpUrlDelay(context, jumpUrl, 0, callBefore, callAfter)
    }

    /**
     * Scheme 路由延遲跳转
     * */
    fun jumpUrlDelay(
        context: Context,
        jumpUrl: String?,
        delay: Long,
        callBefore: ((context: Context, action: RouterAction) -> Unit)? = null,
        callAfter: ((context: Context, json: String?) -> Unit)? = null
    ) {
        if (delay > 0L) {
            Observable.timer(delay, TimeUnit.MILLISECONDS)
                .compose(RxUtils.schedulerIO2Main())
                .subscribeEx {
                    onNextEx {
                        mSchemeHelper.jumpUrl(context, jumpUrl, callBefore, callAfter)
                    }
                }
        } else {
            mSchemeHelper.jumpUrl(context, jumpUrl, callBefore, callAfter)
        }
    }

    /**
     * 创建 Scheme 路由
     * */
    fun createUrl(action: RouterAction): String {
        return mSchemeHelper.createSchemeUrl(action)
    }


    /**
     * 注册自己业务的路由处理器
     * 处理后如果有数据需要返回
     * 统一使用Json字符串格式返回
     * */
    fun registerRouterCall(
        path: String,
        handler: IRouterCall
    ) {
        mSchemeHelper.registerCall(path, handler)
    }

    fun registerRouterCall(
        map: Map<String, IRouterCall>
    ) {
        map.forEach {
            mSchemeHelper.registerCall(it.key, it.value)
        }
    }

    /**
     * 添加拦截器
     * 不指定优先级，则先添加的优先级就越高
     * */
    fun addInterceptor(interceptor: IRouterInterceptor) {
        mIntercepts.addInterceptor(interceptor)
    }

    /**
     * 添加拦截器
     * */
    fun addInterceptor(interceptor: IRouterInterceptor, priority: Int) {
        mIntercepts.addInterceptor(interceptor, priority)
    }

    fun getIntercepts(): InterceptGroup {
        return mIntercepts
    }

    // 测试生成 Scheme 路由
    fun testCreateUrl() {
        val action = RouterAction()
        action.action_type = CommRouter.Scheme.ACTION_TYPE_CALL
        action.page_type = CommRouter.Scheme.PAGE_TYPE_NATIVE
        action.path = UserRouter.Call.GET_USER_INFO
        val jsonObj = JsonObject()
        jsonObj.addProperty(CommConstant.Key.KEY_INTERCEPTOR_LOGIN, "1")
        action.params = jsonObj
        createUrl(action)
    }

}